﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;
using System.Windows.Forms;
using Microsoft.Xna.Framework;

using AimGameLibrary;
using AimGameEngine.EditorObject;

namespace AimGameEngine
{
    public enum BackupMode
    { 
        Position,
        Edit,
        DeleteNode,
        DeleteLink,
        CreateNode,
        CreateLink
    }
    public class PackSave : ToolStripTextBox
    {
        public ArrayList inputpacket;
        public BackupMode inputmode;

        public PackSave(ArrayList inputpacket,BackupMode inputmode)
        {
            this.inputpacket = (ArrayList)inputpacket.Clone();
            this.inputmode = inputmode;

            if (inputmode == BackupMode.Position)
                this.Text = GetPosition().ToString();
            else if (inputmode == BackupMode.Edit)
                this.Text = BackupMode.Edit.ToString() + " " + GetName();
            else if (inputmode == BackupMode.DeleteNode)
                this.Text = BackupMode.DeleteNode.ToString() + " " + GetNode().ToString();
            else if (inputmode == BackupMode.DeleteLink)
                this.Text = BackupMode.DeleteLink.ToString();
            else if (inputmode == BackupMode.CreateNode)
                this.Text = BackupMode.CreateNode.ToString() + " " + GetNode().ToString();
            else if (inputmode == BackupMode.CreateLink)
                this.Text = BackupMode.CreateLink.ToString();

            this.Enabled = false;
        }

        public Vector2 GetPosition()
        {
            if (inputpacket.Count > 2 && inputpacket[2].GetType() == typeof(Point))
            {
                Point temp = (Point)inputpacket[2];
                return new Vector2(temp.X,temp.Y);
            }
            else return Vector2.Zero;
        }

        public String GetName()
        {
            if (inputpacket.Count > 0 )
            {
                NodeData tempdata = (NodeData)inputpacket[0];
                return tempdata.MyName;
            }
            else return "NULL";
        }

        public NodeObject GetNode()
        {
            return (NodeObject)inputpacket[0];
        }

    }

    public class BackupActionsControl : CallBack
    {
        public ArrayList Temp;
        public String Test;
        ToolStripSplitButton UndoButton;
        ToolStripSplitButton RedoButton;
        public bool Doing;

        public BackupActionsControl()
        {
            Temp = new ArrayList();
            Doing = false;
        }

        public void SetupButton(ToolStripSplitButton UndoButton, ToolStripSplitButton RedoButton)
        {
            this.UndoButton = UndoButton;
            this.RedoButton = RedoButton;
            
            CheckEnabled();
        }

        public PackSave UndoAction(Dictionary<String, NodeObject> input)
        {
            PackSave temp = (PackSave)UndoButton.DropDownItems[0];

            if (temp.inputmode == BackupMode.Position)
            {
                #region Position
                if (UndoButton.DropDownItems.Count > 0)
                    if (input.ContainsKey(temp.GetName()))
                    {
                        TempSave(input[temp.GetName()], BackupMode.Position);
                        RedoButton.DropDownItems.Insert(0, new PackSave(Temp, BackupMode.Position));
                        UndoButton.DropDownItems.RemoveAt(0);
                        input[temp.GetName()].MyViewData.Position = temp.GetPosition();
                    }
                #endregion
            }
            else if (temp.inputmode == BackupMode.Edit)
            {
                #region Edit
                if (UndoButton.DropDownItems.Count > 0)
                    if (input.ContainsKey(temp.GetName()))
                    {
                        TempSave(input[temp.GetName()], BackupMode.Edit);
                        RedoButton.DropDownItems.Insert(0, new PackSave(Temp, BackupMode.Edit));
                        UndoButton.DropDownItems.RemoveAt(0);
                        Identification getdata = new Identification();
                        getdata.Items = temp.inputpacket.ToArray();
                        input[temp.GetName()].LoadData(getdata, 1);
                    }
                #endregion
            }
            else if (temp.inputmode == BackupMode.DeleteNode)
            {
                #region Node
                if (temp.GetNode() != null)
                {
                    Temp.Clear();
                    Temp = (ArrayList)temp.inputpacket.Clone();

                    temp.GetNode().AddMetoList();
                    RedoButton.DropDownItems.Insert(0, UndoButton.DropDownItems[0]);
                }
                #endregion
            }
            else if (temp.inputmode == BackupMode.DeleteLink)
            {
                #region Link
                Temp.Clear();
                Temp = (ArrayList)temp.inputpacket.Clone();

                RedoButton.DropDownItems.Insert(0, new PackSave(Temp, BackupMode.DeleteLink));
                UndoButton.DropDownItems.RemoveAt(0);
                #endregion
            }
            else if (temp.inputmode == BackupMode.CreateNode)
            {
                #region Node
                if (temp.GetNode() != null)
                {
                    Temp.Clear();
                    Temp = (ArrayList)temp.inputpacket.Clone();

                    temp.GetNode().Remove();
                    RedoButton.DropDownItems.Insert(0, UndoButton.DropDownItems[0]);
                }
                #endregion
            }
            else if (temp.inputmode == BackupMode.CreateLink)
            {
                #region Link
                Temp.Clear();
                Temp = (ArrayList)temp.inputpacket.Clone();

                RedoButton.DropDownItems.Insert(0, new PackSave(Temp, BackupMode.CreateLink));
                UndoButton.DropDownItems.RemoveAt(0);
                #endregion
            }

            CheckEnabled();
            return temp;
        }

        public PackSave RedoAction(Dictionary<String, NodeObject> input)
        {
            PackSave temp = (PackSave)RedoButton.DropDownItems[0];

            if (temp.inputmode == BackupMode.Position)
            {
                #region Position
                if (RedoButton.DropDownItems.Count > 0)
                    if (input.ContainsKey(temp.GetName()))
                    {
                        TempSave(input[temp.GetName()], BackupMode.Position);
                        UndoButton.DropDownItems.Insert(0, new PackSave(Temp, BackupMode.Position));
                        RedoButton.DropDownItems.RemoveAt(0);
                        input[temp.GetName()].MyViewData.Position = temp.GetPosition();
                    }
                #endregion
            }
            else if (temp.inputmode == BackupMode.Edit)
            {
                #region Edit
                if (RedoButton.DropDownItems.Count > 0)
                    if (input.ContainsKey(temp.GetName()))
                    {
                        TempSave(input[temp.GetName()], BackupMode.Edit);
                        UndoButton.DropDownItems.Insert(0, new PackSave(Temp, BackupMode.Edit));
                        RedoButton.DropDownItems.RemoveAt(0);
                        Identification getdata = new Identification();
                        getdata.Items = temp.inputpacket.ToArray();
                        input[temp.GetName()].LoadData(getdata, 1);
                    }
                #endregion
            }
            else if (temp.inputmode == BackupMode.DeleteNode)
            {
                #region Node
                if (temp.GetNode() != null)
                {
                    Temp.Clear();
                    Temp = (ArrayList)temp.inputpacket.Clone();

                    temp.GetNode().Remove();
                    UndoButton.DropDownItems.Insert(0, RedoButton.DropDownItems[0]);
                }
                #endregion
            }
            else if (temp.inputmode == BackupMode.DeleteLink)
            {
                #region Link
                Temp.Clear();
                Temp = (ArrayList)temp.inputpacket.Clone();
                
                UndoButton.DropDownItems.Insert(0, new PackSave(Temp, BackupMode.DeleteLink));
                RedoButton.DropDownItems.RemoveAt(0);
                #endregion
            }
            else if (temp.inputmode == BackupMode.CreateNode)
            {
                #region Node
                if (temp.GetNode() != null)
                {
                    Temp.Clear();
                    Temp = (ArrayList)temp.inputpacket.Clone();

                    temp.GetNode().AddMetoList();
                    UndoButton.DropDownItems.Insert(0, RedoButton.DropDownItems[0]);
                }
                #endregion
            }
            else if (temp.inputmode == BackupMode.CreateLink)
            {
                #region Link
                Temp.Clear();
                Temp = (ArrayList)temp.inputpacket.Clone();

                UndoButton.DropDownItems.Insert(0, new PackSave(Temp, BackupMode.CreateLink));
                RedoButton.DropDownItems.RemoveAt(0);
                #endregion
            }

            CheckEnabled();
            return temp;
        }

        public void TempSave(object node,BackupMode inputMode)
        {
            Temp.Clear();
            if (inputMode == BackupMode.DeleteNode)
            {
                Temp.Add(node);
                NodeObject temp = (NodeObject)node;
                foreach (LinkLine link in temp.LinklinetoConnecter)
                {
                    Temp.Add(new Point((int)link.Start.X, (int)link.Start.Y));
                    Temp.Add(new Point((int)link.End.X, (int)link.End.Y));
                }
            }
            else if (inputMode == BackupMode.CreateNode)
            {
                Temp.Add(node);
            }
            else if (inputMode == BackupMode.DeleteLink || inputMode == BackupMode.CreateLink)
            {
                //Temp.Add(node);
                if (node.GetType() == typeof(LinkLine))
                {
                    LinkLine link = (LinkLine)node;
                    Temp.Add(link.StartConnecter);
                    Temp.Add(link.EndConnecter);
                }
            }
            else
            {
                NodeObject temp = (NodeObject)node;
                temp.SaveData(Temp, SaveMode.Project);
            }
        }

        public override void Deactivate(object sender, EventArgs e)
        {
            base.Deactivate(sender, e);
            BackupMove(BackupMode.Edit);
        }

        public void BackupMove(BackupMode inputMode)
        {
            PackSave input = new PackSave(Temp, inputMode);
            Temp.Clear();

            UndoButton.DropDownItems.Insert(0, input);
            ClearRedo();
            CheckEnabled();
        }

        public void ClearAll()
        {
            RedoButton.DropDownItems.Clear();
            UndoButton.DropDownItems.Clear();
            CheckEnabled();
        }

        public void ClearRedo()
        {
            if (RedoButton.DropDownItems.Count > 0)
                RedoButton.DropDownItems.Clear();
        }

        void CheckEnabled()
        {
            if (UndoButton.DropDownItems.Count > 0)
                UndoButton.Enabled = true;
            else UndoButton.Enabled = false;

            if (RedoButton.DropDownItems.Count > 0)
                RedoButton.Enabled = true;
            else RedoButton.Enabled = false;
        }
    }
}
